#include "TaskApi.h"

SyncTaskApi::RemoteApiResult SyncTaskApi::createRemoteTask(const QString userName){
    const QString queryStrUrl = TaskApi::TASK_GEN + "?user=" + userName;

    // manager
    QNetworkAccessManager manager;

    // request
    QNetworkRequest request;
    request.setUrl(queryStrUrl);

    // run
    QNetworkReply *reply = manager.get(request);

    // wait
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    // get task_id
    int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QString taskId = "";
    QString errorMsg = "";
    if(reply->error() == QNetworkReply::NoError){
        QString res = reply->readAll();

        QJsonDocument json = QJsonDocument::fromJson(res.toUtf8());
        QJsonObject jsonObj = json.object();
        taskId = jsonObj["res"].toString();
    }else{
        errorMsg = reply->errorString();
    }

    reply->deleteLater();
    return SyncTaskApi::RemoteApiResult{code, taskId, errorMsg};
}

SyncTaskApi::RemoteApiResult SyncTaskApi::uploadFileToTask(const QString taskId, const QVector<QString>& fileList){
    const QString queryStrUrl = TaskApi::TASK_POST;

    // manager
    QNetworkAccessManager manager;

    // request
    QNetworkRequest request;
    request.setUrl(queryStrUrl);

    // formdata
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);

    // filedata
    for(const QString& each : fileList){
        QFileInfo fileInfo(each);
        QString fixName = Helper::_fixName(fileInfo.fileName());

        QFile *file = new QFile(each);
        file->open(QIODevice::ReadOnly);
        file->setParent(multiPart);

        QHttpPart part;
        part.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QString("form-data; name=\"%1\"; filename=\"%2\"").arg("files", fixName));
        part.setBodyDevice(file);
        multiPart->append(part);
    }

    // query data
    QHttpPart part;
    part.setHeader(QNetworkRequest::ContentDispositionHeader,
                   QString("form-data; name=\"query_key\""));
    part.setBody(taskId.toUtf8());
    multiPart->append(part);

    // post
    QNetworkReply *reply = manager.post(request, multiPart);

    // wait
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    // get
    int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QString okMsg = "";
    QString errorMsg = "";
    if(reply->error() == QNetworkReply::NoError){
        okMsg = reply->readAll();
    }else{
        errorMsg = reply->errorString();
    }

    reply->deleteLater();
    return SyncTaskApi::RemoteApiResult{code, okMsg, errorMsg};
}

SyncTaskApi::RemoteApiResult SyncTaskApi::putTask(const QString taskId, const QString options){
    const QString queryStrUrl = TaskApi::Task_IN + "?query_key=" + taskId + "&running_options=" + options;

    // manager
    QNetworkAccessManager manager;

    // request
    QNetworkRequest request;
    request.setUrl(queryStrUrl);

    // run
    QByteArray data;
    QNetworkReply *reply = manager.put(request, data);

    // wait
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    // get
    int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QString okMsg = "";
    QString errorMsg = "";
    if(reply->error() == QNetworkReply::NoError){
        okMsg = reply->readAll();
    }else{
        errorMsg = reply->errorString();
    }

    reply->deleteLater();
    return SyncTaskApi::RemoteApiResult{200, okMsg, errorMsg};
}

SyncTaskApi::ApiTaskProgress SyncTaskApi::taskQuery(const QString taskId){
    const QString queryStrUrl = TaskApi::TASK_QUERY + "?query_key=" + taskId;

    // manager
    QNetworkAccessManager manager;

    // request
    QNetworkRequest request;
    request.setUrl(queryStrUrl);

    // run
    QByteArray data;
    QNetworkReply *reply = manager.get(request);

    // wait
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    // get
    SyncTaskApi::ApiTaskProgress returnInfo;
    returnInfo.code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    if(reply->error() == QNetworkReply::NoError){
        returnInfo.result = reply->readAll();
        QJsonDocument json = QJsonDocument::fromJson(returnInfo.result.toUtf8());
        QJsonObject jsonObj = json.object();
        returnInfo.taskStatus = jsonObj["status"].toInt();
        returnInfo.taskMsg = jsonObj["msg"].toString();
        returnInfo.taskProgrss = jsonObj["progress"].toDouble();
    }else{
        returnInfo.errMsg = reply->errorString();
    }

    reply->deleteLater();
    return returnInfo;
}

SyncTaskApi::RemoteApiResult SyncTaskApi::resultQuery(const QString taskId, const QString fileName, const QString options){
    QString fixFileName = Helper::_fixName(fileName);
    const QString queryStrUrl = TaskApi::RESULT_QUERY + "?query_key=" + taskId + "&file_name=" + fixFileName + "&running_options=" + options;

    // manager
    QNetworkAccessManager manager;

    // request
    QNetworkRequest request;
    request.setUrl(queryStrUrl);

    // run
    QNetworkReply *reply = manager.get(request);

    // wait
    QEventLoop loop;
    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
    loop.exec();

    // get
    int code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QString okMsg = "";
    QString errorMsg = "";
    if(reply->error() == QNetworkReply::NoError){
        okMsg = reply->readAll();
    }else{
        errorMsg = reply->errorString();
    }

    reply->deleteLater();
    return SyncTaskApi::RemoteApiResult{code, okMsg, errorMsg};
}
